﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Web.UI;
using HelpersDotNet.Extensions;

namespace HelpersDotNet.Compression
{
    public class GZipCompressor : ICompressor, IStateFormatter
    {
        public GZipCompressor() { }

        #region ICompressor Members

        public byte[] Compress(byte[] data)
        {
            using (MemoryStream output = new MemoryStream())
            {
                using (GZipStream gzip = new GZipStream(output, CompressionMode.Compress))
                {
                    gzip.Write(data, 0, data.Length);
                }
                return output.ToArray();
            }
        }

        public byte[] Decompress(byte[] data)
        {
            using (MemoryStream input = new MemoryStream())
            {
                input.Write(data, 0, data.Length);
                input.Position = 0;

                using (GZipStream gzip = new GZipStream(input, CompressionMode.Decompress))
                {
                    using (MemoryStream output = new MemoryStream())
                    {
                        byte[] buff = new byte[64];
                        int read = -1;
                        read = gzip.Read(buff, 0, buff.Length);

                        while (read > 0)
                        {
                            output.Write(buff, 0, buff.Length);
                            read = gzip.Read(buff, 0, buff.Length);
                        }
                        return output.ToArray();
                    }
                }
            }
        }

        #endregion

        #region IStateFormatter Members

        public object Deserialize(string serializedState)
        {
            byte[] bytes = Convert.FromBase64String(serializedState);
            bytes = this.Decompress(bytes);
            LosFormatter formatter = new LosFormatter();
            return formatter.Deserialize(Convert.ToBase64String(bytes));
        }

        public string Serialize(object state)
        {
            LosFormatter formatter = new LosFormatter();
            using (StringWriter writer = new StringWriter())
            {
                formatter.Serialize(writer, state);
                string s = writer.ToString();
                byte[] bytes = Convert.FromBase64String(s);
                bytes = this.Compress(bytes);
                return Convert.ToBase64String(bytes);
            }
        }

        #endregion
    }
}
